﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Poli.IA.GA
{
    public class Individuo
    {
        public List<Musica> PlayList { get; set; }
        public int Fitness { get; set; }
        public Individuo()
        {
            PlayList = new List<Musica>();
            Fitness = 0;
        }

        public void InicializarIndividuo(List<Musica> source)
        {

            while (PlayList.Count < 10)
            {
                Random r = new Random(DateTime.Now.Millisecond);
                int index = r.Next(source.Count);
                PlayList.Add(source[index]);
                source.RemoveAt(index);
            }
        }

        public void Mutacao(List<Musica> source, Perfil perfilSelecionado)
        {
            Random r = new Random(DateTime.Now.Millisecond);
            Musica musica = null;
            Musica novaMusica = null;
            Individuo newInd = null;
            int oldFitness = TestarFitness(perfilSelecionado);
            List<Musica> newPlaylist = new List<Musica>();
            List<Musica> newSource = new List<Musica>();
            foreach (Musica music in source)
            {
                newSource.Add(new Musica(music.Nome, music.Artista, music.Estilo, music.Nacionalidade, music.Decada, music.Hit, music.Tendencia, music.Ritmo));
            }
            foreach (Musica music in PlayList)
            {
                newPlaylist.Add(new Musica(music.Nome, music.Artista, music.Estilo, music.Nacionalidade, music.Decada, music.Hit, music.Tendencia, music.Ritmo));
            }
            //newPlaylist = PlayList;
            for (int i = 0; i < newPlaylist.Count; i++)
            {

                if (r.Next(100) < 20)
                {
                    musica = new Musica(newPlaylist[i].Nome, newPlaylist[i].Artista, newPlaylist[i].Estilo, newPlaylist[i].Nacionalidade,
                    newPlaylist[i].Decada, newPlaylist[i].Hit, newPlaylist[i].Tendencia, newPlaylist[i].Ritmo);
                    //source.Add(musica);
                    Musica toDelete = newPlaylist.Find(m => m.Nome == musica.Nome);
                    //newPlaylist.Remove(toDelete);
                    int indice = r.Next(newSource.Count);
                    novaMusica = new Musica(newSource[indice].Nome, newSource[indice].Artista, newSource[indice].Estilo, newSource[indice].Nacionalidade,
                    newSource[indice].Decada, newSource[indice].Hit, newSource[indice].Tendencia, newSource[indice].Ritmo);
                    //newPlaylist.Add(novaMusica);
                    Musica srcDelete = newSource.Find(m => m.Nome == novaMusica.Nome);
                    //source.Remove(srcDelete);
                    if (!newPlaylist.Exists(m => m.Nome == novaMusica.Nome))
                    {
                        newSource.Add(musica);
                        newPlaylist.Remove(toDelete);
                        newPlaylist.Add(novaMusica);
                        newSource.Remove(srcDelete);
                        newInd = new Individuo();
                        newInd.PlayList = newPlaylist;
                    }
                }
            }
            int newFitness = 0;
            if (newInd != null)
            {
                newFitness = newInd.TestarFitness(perfilSelecionado);
            }

            if (newFitness >= oldFitness)
            {
                PlayList = newPlaylist;
                source = newSource;
            }

        }

        public int CalcularFitness(Perfil perfilSelecionado)
        {
            int fitness = 0;
            foreach (Musica musica in PlayList)
            {
                fitness += musica.CalcularFitness(perfilSelecionado);
            }
            Fitness = fitness;
            return Fitness;
        }

        public int TestarFitness(Perfil perfilSelecionado)
        {
            int fitness = 0;
            foreach (Musica musica in PlayList)
            {
                fitness += musica.CalcularFitness(perfilSelecionado);
            }
            //Fitness = fitness;
            return fitness;
        }
    }
}
